<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <button id="button">点击</button>
    <script>
      // function fun(n, o) {
      //     console.log(o);
      //     return {
      //         fun: function (m) {
      //             return fun(m, n);
      //         }
      //     };
      // }

      // var a = fun(0); // ?  undefined
      // a.fun(1); // ?   0
      // a.fun(2); // ?   0
      // a.fun(3); // ?   0
      // var b = fun(0).fun(1).fun(2).fun(3); // ?  undefined  0       1      2
      // //
      // var c = fun(0).fun(1); // ?     undefined  0
      // c.fun(2); // ?   1
      // c.fun(3); // ?   1
      //====>> 闭包就是能够读取其他函数内部变量的函数
      // 由于在Javascript语言中，只有函数内部的子函数才能读取局部变量，因此可以把闭包简单理解成"定义在一个函数内部的函数"。

      /**
       * 它的最大用处有两个:
       * 1、可以读取函数内部的变量
       * 2、让这些变量的值始终保持在内存中
       */

      /**
       * 使用闭包的注意点
       * 1、由于闭包会使得函数中的变量都被保存在内存中，内存消耗很大，所以不能滥用闭包，否则会造成网页的性能问题，
       *    在IE中可能导致内存泄露。解决方法是，在退出函数之前，将不使用的局部变量全部删除
       * 2、闭包会在父函数外部，改变父函数内部变量的值。所以，如果你把父函数当作对象（object）使用，
       *    把闭包当作它的公用方法（Public Method），把内部变量当作它的私有属性（private value），
       *    这时一定要小心，不要随便改变父函数内部变量的值
       */
      function fn() {
        var a = 10;
        return function (m) {
          a = a + m;
          console.log(a);
        };
      }
      var f = fn();
      f(1);
      f(1);
      f(1);

      function fun(a) {
        return function (b) {
          return function (falg) {
            if (falg === "+") {
              return a + b;
            } else if (falg === "*") {
              return a * b;
            }
          };
        };
      }
      let sum1 = fun(2)(3)("+");
      let sum2 = fun(2)(3)("*");
      console.log(sum1);
      console.log(sum2);

      function createIncrease() {
        const doms = new Array(100000).fill(0).map((item, index) => {
          const dom = document.createElement("div");
          dom.innerHTML = index.toString();
          return dom;
        });

        function increase() {}
        function add() {
          doms;
        }
        return increase;
      }
      // 方法1 从浏览器控制台的内存分析上看 点击后并不会新增10万个节点，可能垃圾回收器自动回收了
      function handleClick() {
        console.log("点击按钮==");
        const increase = createIncrease();
      }
      const btn = document.querySelector("#button");
      btn.addEventListener("click", handleClick);

      // 方法2 提前定义 increase；会使得内存增大，新增10万的游离节点 垃圾回收无法自动回收
      let increase;
      function handleClick2() {
        increase = createIncrease();
      }
    </script>
  </body>
</html>
